package springboot.controller;


import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
public class downloadTest {
	
	@GetMapping("/hello/{id}/{name}")
	@ResponseBody
	public String sayHello(@PathVariable String id, @PathVariable String name) {
		return "id:" + id + "name:" + name;
	}
	
	
	@RequestMapping(value = "/file/download")
	@ResponseBody
	public String download(HttpServletRequest request, HttpServletResponse response) {
		
		File file = new File(request.getParameter("fileName"));
		if (file.exists()) {
			String range = request.getHeader("Range");
			if (range != null && (range = range.trim()).length() > 0) {
				Pattern rangePattern = Pattern.compile("^bytes=([0-9]&#43;)-([0-9]&#43;)?$");
				Matcher matcher = rangePattern.matcher(range);
				if (matcher.find()) {
					int start = Integer.parseInt(matcher.group(1));
					int end = 0;
					String endStr = matcher.group(2);
					if (endStr != null && (endStr = endStr.trim()).length() > 0)
						end = Integer.parseInt(endStr);
					downLoadByBreakpoint(file, start, end, response);
					return null;
				}
			}
			downLoadAll(file, response);
			return null;
		}
		return "文件不存在";
	}
	
	
	public void downLoadAll(File file, HttpServletResponse response) {
		OutputStream stream = null;
		BufferedInputStream fif = null;
		try {
			stream = response.getOutputStream();
			response.reset();
			response.setContentType("application/octet-stream");
			response.setHeader("Content-disposition", "attachment; filename=" + file.getName());
			response.setHeader("Content-Length", String.valueOf(file.length()));
			fif = new BufferedInputStream(new FileInputStream(file));
			int d;
			byte[] buf = new byte[10240];
			while ((d = fif.read(buf)) != -1) {
				stream.write(buf, 0, d);
			}
			stream.flush();
		} catch (Exception e) {
			try {
				if (stream != null)
					stream.close();
				if (fif != null)
					fif.close();
			} catch (Exception e11) {
				e11.printStackTrace();
			}
		}
	}
	
	public void downLoadByBreakpoint(File file, long start, long end, HttpServletResponse response) {
		OutputStream stream = null;
		RandomAccessFile fif = null;
		try {
			if (end <= 0) {
				end = file.length() - 1;
			}
			stream = response.getOutputStream();
			response.reset();
			response.setStatus(206);
			response.setContentType("application/octet-stream");
			response.setHeader("Content-disposition", "attachment; filename=" + file.getName());
			response.setHeader("Content-Length", String.valueOf(end - start + 1));
			response.setHeader("Accept-Ranges", "bytes");
			response.setHeader("Content-Range", String.format("bytes %s-%s/%s", start, end, file.length()));
			fif = new RandomAccessFile(file, "r");
			fif.seek(start);
			long index = start;
			int d;
			byte[] buf = new byte[10240];
			while (index != end && (d = fif.read(buf)) != -1) {
				if (index + d > end) {
					d = (int) (end - index + 1);
				}
				index += d;
				stream.write(buf, 0, d);
			}
			stream.flush();
		} catch (Exception e) {
			try {
				if (stream != null) {
					stream.close();
				}
				if (fif != null) {
					fif.close();
				}
			} catch (Exception e11) {
				e11.printStackTrace();
			}
		}
	}
}
